package com.example.springboot.filter;

import com.alibaba.fastjson.JSON;
import com.example.springboot.config.Result;
import com.example.springboot.constant.ConstantKey;
import com.example.springboot.entity.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authenticationManager;

    public JWTLoginFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
            List<GrantedAuthority> authorityList = new ArrayList<>();
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(),
                    user.getPassword(),
                    authorityList);
            Authentication authenticate = authenticationManager.authenticate(token);
            return authenticate;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException, ServletException {
        String token = null;
        Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();
        List roleList = new ArrayList();
        for (GrantedAuthority grantedAuthority: authorities) {
            roleList.add(grantedAuthority);
        }
        Calendar instance = Calendar.getInstance();
        Date now = instance.getTime();
        instance.setTime(new Date());
        instance.add(Calendar.MINUTE,5);
        Date time = instance.getTime();
        token = Jwts.builder().setSubject(authResult.getName() + "-" + roleList)
            .setIssuedAt(now)
            .setExpiration(time)
            .signWith(SignatureAlgorithm.HS512, ConstantKey.SIGNING_KEY)
            .compact();
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("Authorization","Basic " + token);
        Result result = Result.ok(resultMap);
        response.getWriter().write(JSON.toJSONString(result));
    }
}
